package com.example.springbootlearn.security.config;


import cn.hutool.json.JSONUtil;
import com.example.springbootlearn.security.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.UrlAuthorizationConfigurer;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class SecurityConf extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Autowired
    private CustomSecurityMetadataSource customSecurityMetadataSource;


    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ApplicationContext applicationContext = http.getSharedObject(ApplicationContext.class);
        http.apply(new UrlAuthorizationConfigurer<>(applicationContext))
                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {

                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O object) {
                        object.setSecurityMetadataSource(customSecurityMetadataSource);
                        object.setRejectPublicInvocations(false);
                        return object;
                    }
                });

        http.formLogin()
                .successHandler((request, response, authentication) -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("status", 200);
                    map.put("msg", "登录成功");
                    response.setContentType("application/json;charset=UTF-8");
                    response.getWriter().write(JSONUtil.toJsonStr(map));
                })
                .failureHandler((request, response, exception) -> {
                    response.setContentType("application/json;charset=UTF-8");
                    Map<String, Object> resp = new HashMap<>();
                    resp.put("status", 500);
                    resp.put("msg", "登录失败!" + exception.getMessage());
                    response.getWriter().write(JSONUtil.toJsonStr(resp));
                })
                .and()
                .logout()
                .logoutUrl("/logout")
                .invalidateHttpSession(true)
                .clearAuthentication(true)
                .logoutSuccessHandler((request, response, authentication) -> {
                    response.setContentType("application/json;charset=UTF-8");
                    Map<String, Object> map = new HashMap<>();
                    map.put("status", 200);
                    map.put("msg", "注销成功");
                    response.setContentType("application/json;charset=UTF-8");
                    response.getWriter().write(JSONUtil.toJsonStr(map));
                })
//                .logoutSuccessUrl("/login.html")
                .and().authorizeRequests().antMatchers("/login").permitAll().and().csrf().disable();
    }


    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/resources/**", "/guest/test", "encrypt");
    }

}
